package ${domain}.frame.schedule;

import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import ${domain}.frame.auth.LocalData;
import ${domain}.frame.utils.LogUtil;
import ${domain}.module.wsys.mgr.LogtaskManager;
import ${domain}.module.wsys.req.LogtaskCreateRequest;

import java.util.Date;
import java.util.concurrent.ScheduledFuture;

/**
 * 抽象任务
 *
 * @author wangbing
 * @version 0.0.1
 * @since 2020-01-01
 */
public abstract class RunTask implements Runnable {

    public abstract String taskId();

    protected abstract void task();

    public String taskName() {
        return "";
    }

    public String taskNote() {
        return "";
    }

    @Override
    public void run() {
        LogtaskCreateRequest request = new LogtaskCreateRequest();
        request.setTaskId(taskId());
        request.setTaskName(taskName());
        request.setStartTime(new Date());
        try {
            boolean before = before();
            if (before) {
                task();
            }
            after();
            request.setExecState("1");
            request.setExecResult("成功");
            request.setEndTime(new Date());
        } catch (Exception e) {
            exception(e);
            // 保证异常信息不会超过字段长度
            String trace = LogUtil.getTrace(e);
            if (trace.length() > 496) {
                trace = trace.substring(0, 496);
            }
            request.setExecState("0");
            request.setExecResult(String.format("失败[%s]", trace));
            request.setEndTime(new Date());
        }
        try {
            // 任务执行结果
            request.setExecTime((int) (request.getEndTime().getTime() - request.getStartTime().getTime()));
            LogtaskManager logtaskManager = LocalData.getBean(LogtaskManager.class);
            assert logtaskManager != null;
            logtaskManager.create(request, LocalData.getSysToken());
            // todo 考虑是否将任务的异常归为故障
        } catch (Exception ignored) {

        }
    }

    /**
     * 任务执行前执行
     *
     * @return 是否继续执行任务
     */
    protected boolean before() {
        return true;
    }

    /**
     * 任务执行后执行
     */
    protected void after() {
    }

    /**
     * 执行任务异常处理
     */
    protected void exception(Exception e) {
        e.printStackTrace();
    }

    public abstract ScheduledFuture<?> schedule(ThreadPoolTaskScheduler poolTaskScheduler);
}